This invention is directed to a method and apparatus for object-to-object JAVA Native interfacing. More particularly, the present invention is directed to a method and apparatus for facilitating the direct implementation of native or legacy code in the JAVA runtime environment.
Virtual machines and particularly managed code executing within them are becoming increasingly popular due to several important benefits they provide: platform independence, execution stability and availability of development tools. Managed code is that code of a program that executes in a virtual machine environment and specifically has its memory allocation managed by that virtual machine.
However, no matter how lucrative rewriting all existing applications in managed code sounds, it is a most impractical undertaking. At the very least, rewriting must happen gradually in iterations, thereby being more cost effective and manageable.
The question that then arises is one of how to interface with legacy applications with significant importance to any managed code application. One of the difficulties architects of virtual machines have to overcome is how to enable communication between the virtual machines and the existing applications that run outside that environment.
Although virtual machines are of a quite old computing concept, it wasn't until recently that commercial vendors were able to actually construct machines that are commercially viable and contain the runtime capabilities to scale as needed. Sun Microsystems and their JAVA platform are considered to be the first such vendor and environment, e.g., Sun JAVA 2 Native Interface.
JAVA Native Interface or JNI, is designed with the objective of being generic enough that it enables JAVA applications to invoke any native code without regard to the native code's programming language. This rationale, for example, led to the tools provided for in JNI bridge development producing C language functions, which is by far the most generic and native-friendly programming language.
In JAVA programming, an object is a software bundle of related variables and methods. Software objects all have state and behavior. Each software object maintains its state in one or more variables. A variable is an item of data named by an identifier. A software object implements its behavior with methods, whereas a method is a function (subroutine) associated with an object. To clarify, everything that a software object knows (state) and can do (behavior) is expressed by the variables and methods within that object. Variables, formally known as instance variables, contain the state for a particular object. Instance methods inspect or change the state of a particular instance.
An object's variables make up the center, or nucleus, of the object. Methods surround and hide the object's nucleus from other objects in the program. Encapsulation is used to define the packaging of an object's variables within the protective custody of its methods. In JAVA, an object can specify one of four different access levels for each of its variables and methods. These levels determine which other objects and classes may access that particular variable or method. A class is a blueprint, or prototype that defines the variables and methods common to all objects of a certain kind, thus, an object is typically an instance of some class. To state another way, a class consists of a group of related methods and variables lumped together under one name.
In C++, objects are normally identified by their address (pointer). This address, if used improperly, can cause severe and hard-to-find damage to the program. Examples of such improper usage are double-free, stale pointers usage, and the like. The “smart pointer”, or object reference management, replaces the object pointer with an object reference, a separate lightweight object which is managed independently from the object, much like object references in JAVA. Class Loaders use these pointers to locate the corresponding class file on disk, read the file into RAM and call java.lang.ClassLoader.defineClass, which tells the system to treat the RAM image as legitimate byte codes.
Some object-oriented languages require that a programmer keep track of all the objects the programmer creates and to explicitly destroy them when they are no longer needed. Managing memory explicitly is tedious and error prone. The JAVA platform uses garbage collection, which allows programmers to create as many objects as desired (limited, of course, by what the user's system can handle), and without worrying about destroying them. The JAVA runtime environment deletes objects when it determines that they are no longer being used.
When there are no more references to a particular object, that object is eligible for garbage collection. References that are held in a variable are usually dropped when the variable goes out of scope. Or, a programmer or user may explicitly drop an object reference by setting the variable to the special value null. A program may have multiple references to the same object; all references to an object must be dropped before the object is eligible for garbage collection. The JAVA runtime environment has a garbage collector that periodically frees the memory used by objects that are no longer referenced.
The majority of legacy code or code that JAVA must communicate with is actually written in C++ or some other object-oriented language. By its nature, C++ is very close concept-wise to JAVA. Both object-oriented languages use classes, objects, native class factories, and the like. In point of fact, C++ and JAVA are so close that they share common language constructs such as keywords, syntax, etc. However, JNI provides only C language binding and lacks the binding required for the C++ language.
Thus there is a need for a method and apparatus to bridge the gap between the JAVA object world and the world of C++ objects.